﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.Script.Serialization;
using System.IO;
using System.Runtime.Serialization.Json;

namespace CloudMusic.Helper
{
    /// <summary>
    /// object转实体类
    /// </summary>
    public class ObjectToEntityHelper
    {

        #region 序列化

        /// <summary>
        /// 将object对象转换为实体对象-list
        /// </summary>
        /// <typeparam name="T">实体对象类名</typeparam>
        /// <param name="asObject">object对象</param>
        /// <returns></returns>
        public static List<T> ConvertObjectByJson<T>(object asObject) where T : new()
        {
            var serializer = new JavaScriptSerializer();
            //将object对象转换为json字符
            var json = serializer.Serialize(asObject);
            //将json字符转换为实体对象
            List<T> t = serializer.Deserialize<List<T>>(json);
            return t;
        }
        /// <summary>
        /// 将object对象转换为实体对象-T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="asObject"></param>
        /// <returns></returns>
        public static T ToUnityByJson<T>(object asObject) where T : new()
        {
            var serializer = new JavaScriptSerializer();
            //将object对象转换为json字符
            var json = serializer.Serialize(asObject);
            //将json字符转换为实体对象
            T t = serializer.Deserialize<T>(json);
            return t;
        }

        /// <summary>
        /// 序列化为JSON
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string Serialize<T>(T obj)
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, obj);
                string retVal = Encoding.Default.GetString(ms.ToArray());
                return retVal;
            }
        }

        /// <summary>
        /// 反序列化为对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T Deserialize<T>(string json)
        {
            T obj = Activator.CreateInstance<T>();
            using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
                obj = (T)serializer.ReadObject(ms);
                ms.Close();
                return obj;
            }
        }
        #endregion

        #region 相同类转换

        /// <summary>
        /// 类转类(T是接收的类型，A是传入数据的类型)
        /// 注意，不可以转换集合，转换集合请用SetListValueByListT方法
        /// 当前类用来转换实体类对象，只是属性和属性的赋值转换
        /// 只转换名字相同并且类型一致的
        /// </summary>
        /// <typeparam name="T">转换结果类型</typeparam>
        /// <typeparam name="A">要转换的类型</typeparam>
        /// <param name="GetValue">传入的参数</param>
        /// <returns>转换结果</returns>
        public static T SetValueByT<T, A>(A GetValue)
        {
            var SetValue = Activator.CreateInstance<T>();
            try
            {
                var TProps = SetValue.GetType().GetProperties();
                var TPropsNames = TProps.ToDictionary(i => i.Name, i => i.GetType());
                var TPropsTypes = TProps.Select(i => i.GetType()).ToList();

                var AProps = GetValue.GetType().GetProperties();

                List<PropertyInfo> Props = new List<PropertyInfo>();
                foreach (var item in AProps)
                {
                    if (TPropsNames.Keys.Contains(item.Name))
                    {
                        if (TPropsNames[item.Name] == item.GetType())
                        {
                            var Value = GetValue.GetType().GetProperty(item.Name).GetValue(GetValue);
                            SetValue.GetType().GetProperty(item.Name).SetValue(SetValue, Value);
                        }
                    }
                }
                return SetValue;
            }
            catch
            {
                return SetValue;
            }
        }

        /// <summary>
        /// 集合转换(T是接收的集合类型，A是传入数据的集合类型)
        /// 当前类用来转换实体类对象，只是属性和属性的赋值转换
        /// 只转换名字相同并且类型一致的
        /// </summary>
        /// <typeparam name="T">转换结果类型</typeparam>
        /// <typeparam name="A">要转换的类型</typeparam>
        /// <param name="GetListValue">传入的集合</param>
        /// <returns>转换结果</returns>
        public static List<T> SetListValueByListT<T, A>(List<A> GetListValue)
        {
            List<T> SetListValue = new List<T>();
            if (GetListValue.Count() > 0)
            {
                var SetDefaultValue = System.Activator.CreateInstance<T>();
                var TProps = SetDefaultValue.GetType().GetProperties();
                var TPropsNames = TProps.ToDictionary(i => i.Name, i => i.GetType());
                var TPropsTypes = TProps.Select(i => i.GetType()).ToList();
                var AProps = GetListValue.First().GetType().GetProperties();

                Dictionary<string, List<object>> list = new Dictionary<string, List<object>>();
                foreach (var item in AProps)
                {
                    if (TPropsNames.Keys.Contains(item.Name))
                    {
                        if (TPropsNames[item.Name] == item.GetType())
                        {
                            List<object> getPropList = GetListValue.Select(i => i.GetType().GetProperty(item.Name).GetValue(i)).ToList();
                            list.Add(item.Name, getPropList);
                        }
                    }
                }
                if (list.Keys.Count > 0)
                {
                    var Count = list.ElementAt(0).Value.Count;
                    for (int i = 0; i < Count; i++)
                    {
                        var NewValue = System.Activator.CreateInstance<T>();
                        foreach (var item in list)
                        {
                            NewValue.GetType().GetProperty(item.Key).SetValue(NewValue, item.Value.ElementAt(i));
                        }
                        SetListValue.Add(NewValue);
                    }
                }
            }
            return SetListValue;
        }

        #endregion
    }
}
